#include "inc/os.h"

extern void trap_vector(void);
extern void do_syscall(struct context *cxt);

void trap_init()
{
	/*
         * set the trap-vector base-address for machine-mode
         */
	w_mtvec((reg_t)trap_vector);
}

reg_t trap_handler(reg_t epc, reg_t cause, context *cxt)
{
	reg_t return_pc = epc;
	reg_t cause_code = cause & 0xfff;
	if(cause & 0x80000000) {
		/* Asynchronous trap - interrupt */
		switch(cause_code) {
			case 3:
                        	uart_puts("software interruption!\n");
                        	break;
                	case 7:
                        	uart_puts("timer interruption!\n");
				timer_handler();
                        	break;
                	case 11:
                        	uart_puts("external interruption!\n");
				uart_int_handler();
                        	break;
                	default:
                        	uart_puts("unknown async exception!\n");
                        	break;
		}
	} else {
		/* Synchronous trap - exception */
                printf("cause = %d\n", cause);
		switch (cause_code) {
                case 11:
                        uart_puts("System call from U-mode!\n");
                        do_syscall(cxt);
                        return_pc += 4;
                        break;
		case 2:
			panic("Illegal instructions!\n");
                default:
                        panic("OOPS! What can I do!");
                        //return_pc += 4;
                }
	}

	return return_pc;
}
